home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / c-lang / vbcc.lha / vbcc / av.c next >
C/C++ Source or Header  |  1996-05-15  |  12KB  |  318 lines

  1. /*  $VER: vbcc (av.c) V0.3     */
  2. /*  aktive Variablen und Elimination unnoetiger Anweisungen */
  3.  
  4. #include "opt.h"
  5.  
  6. /*  fuer aktive Variablen   */
  7. struct Var **vilist;
  8. unsigned int vcount;    /*  0..vcount-rcount-1: vars, vcount-rcount..vcount: DREFOBJs */
  9. unsigned int rcount;
  10. size_t vsize;
  11. unsigned char *av_globals,*av_address,*av_statics,*av_drefs;
  12. int report_dead_statements;
  13.  
  14. void print_av(unsigned char *bitvector)
  15. /*  druckt Variablen in einem Bitvektor */
  16. {
  17.     unsigned int i;
  18.     if(!bitvector) {printf("active variables not available\n");return;}
  19.     for(i=0;i<vcount-rcount;i++)
  20.         if(BTST(bitvector,i)) printf("%3d: %s,%d\n",i,vilist[i]->identifier,vilist[i]->offset);
  21.     for(i=vcount-rcount;i<vcount;i++)
  22.         if(BTST(bitvector,i)) printf("%3d: (%s),%d\n",i,vilist[i]->identifier,vilist[i]->offset);
  23. }
  24. void num_vars(void)
  25. /*  Numeriert Variablen und erzeugt Indexliste  */
  26. {
  27.     unsigned int i,j;struct IC *p;struct Var *v,*a[3],*vp;
  28.     if(DEBUG&1024) printf("numerating variables loop1\n");
  29.     /*  alle Indizes auf -1 */
  30.     a[0]=first_var[0];
  31.     a[1]=first_var[1];
  32.     a[2]=merk_varf;
  33.     for(j=0;j<3;j++){
  34.         v=a[j];
  35.         while(v){
  36.             v->index=-1;
  37.             /*  Variablen von inline-Funktionen */
  38.             if(j==0&&v->fi&&v->fi->first_ic){
  39.                 for(vp=v->fi->vars;vp;vp=vp->next) vp->index=-1;
  40.             }
  41.             v=v->next;
  42.         }
  43.     }
  44.     /*  erst alle Variablen, die als DREFOBJ benutzt werden */
  45.     if(DEBUG&1024) printf("numerating variables loop2\n");
  46.     i=0;
  47.     for(p=first_ic;p;p=p->next){
  48.         if(p->code<LABEL||p->code>BRA){
  49.             if((p->q1.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)&&p->q1.v->index<0)
  50.                 p->q1.v->index=i++;
  51.             if((p->q2.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)&&p->q2.v->index<0)
  52.                 p->q2.v->index=i++;
  53.             if((p->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)&&p->z.v->index<0)
  54.                 p->z.v->index=i++;
  55.         }
  56.     }
  57.     if(DEBUG&1024) printf("numerating variables loop3\n");
  58.     rcount=i;    /*  Anzahl der DREFOBJ-Variablen    */
  59.     /*  jetzt den Rest  */
  60.     for(p=first_ic;p;p=p->next){
  61.         if(p->code<LABEL||p->code>BRA){
  62.             if((p->q1.flags&(VAR|DREFOBJ))==VAR&&p->q1.v->index<0)
  63.                 p->q1.v->index=i++;
  64.             if((p->q2.flags&(VAR|DREFOBJ))==VAR&&p->q2.v->index<0)
  65.                 p->q2.v->index=i++;
  66.             if((p->z.flags&(VAR|DREFOBJ))==VAR&&p->z.v->index<0)
  67.                 p->z.v->index=i++;
  68.         }
  69.     }
  70.     if(DEBUG&1024) printf("numerating variables loop4\n");
  71.     vcount=i+rcount; /*  alle benutzten Variablen+Anzahl der DREFOBJs    */
  72.     vilist=mymalloc(vcount*sizeof(struct Var *));
  73.     for(j=0;j<3;j++){
  74.         int i;
  75.         v=a[j];
  76.         while(v){
  77.             i=v->index;
  78. /*            printf("%s has index %d\n",v->identifier,i);*/
  79.             if(i>=0){
  80.                 if(i>=vcount-rcount) ierror(0);
  81.                 vilist[i]=v;
  82.                 if(i<rcount) vilist[i+vcount-rcount]=v;
  83.             }
  84.             /*  Variablen von inline-Funktionen */
  85.             if(j==0&&v->fi&&v->fi->first_ic){
  86.                 for(vp=v->fi->vars;vp;vp=vp->next){
  87.                     i=vp->index;
  88.                     if(i>=0){
  89.                         if(i>=vcount-rcount) ierror(0);
  90.                         vilist[i]=vp;
  91.                         if(i<rcount) vilist[i+vcount-rcount]=vp;
  92.                     }
  93.                 }
  94.             }
  95.             v=v->next;
  96.         }
  97.     }
  98.  
  99.     vsize=(vcount+CHAR_BIT-1)/CHAR_BIT;
  100.     if(DEBUG&1024) printf("%lu variables (%lu DREFOBJs), vsize=%lu\n",(unsigned long)vcount,(unsigned long)rcount,(unsigned long)vsize);
  101.  
  102.     av_drefs=mymalloc(vsize);
  103.     memset(av_drefs,0,vsize);
  104.     /*  alle DREFOBJs   */
  105.     for(i=vcount-rcount;i<vcount;i++) BSET(av_drefs,i);
  106.  
  107.     /*  av_globals enthaelt alle globalen Variablen und av_address      */
  108.     /*  zusaetzlich noch alle Variablen, deren Adressen genommen wurden */
  109.     av_globals=mymalloc(vsize);
  110.     memset(av_globals,0,vsize);
  111.     av_statics=mymalloc(vsize);
  112.     memset(av_statics,0,vsize);
  113.     av_address=mymalloc(vsize);
  114.     memcpy(av_address,av_globals,vsize);
  115.     for(i=0;i<vcount-rcount;i++){
  116.         if(vilist[i]->nesting==0||vilist[i]->storage_class==EXTERN) BSET(av_globals,i);
  117.         if(vilist[i]->flags&USEDASADR) BSET(av_address,i);
  118.         if(vilist[i]->storage_class==STATIC) BSET(av_statics,i);
  119.         if(i<rcount){
  120.             BSET(av_address,i+vcount-rcount);
  121.             BSET(av_globals,i+vcount-rcount);
  122.         }
  123.     }
  124. }
  125. void print_vi(void)
  126. /*  Druckt vilist und testet Konsistenz */
  127. {
  128.     unsigned int i;
  129.     printf("\nprint_vi()\n");
  130.     for(i=0;i<vcount;i++){
  131.         if(!vilist[i]||(i<rcount&&vilist[i]->index!=i)) ierror(0);
  132.         printf("%3d: %s\n",i,vilist[i]->identifier);
  133.     }
  134. }
  135. void av_change(struct IC *p,unsigned char *use,unsigned char *def)
  136. /*  Berechnet die Aenderungen, die sich durch IC p ergeben  */
  137. /*  tmp muss vom Caller belegt werden                       */
  138. {
  139.     unsigned int i,glflag=0;struct Var *v;
  140.     if(!p) ierror(0);
  141.     if(p->code!=ADDRESS){
  142.         if((p->q1.flags&(VAR|VARADR))==VAR){
  143.             v=p->q1.v;
  144.             i=v->index;
  145.             if(v->nesting==0||(v->flags&USEDASADR)) glflag|=1;
  146.             if(i>=vcount) {pric2(stdout,p);ierror(0);}
  147.             if(!BTST(def,i)) BSET(use,i);
  148.             if((p->q1.flags&DREFOBJ)&&!BTST(def,i+vcount-rcount)) BSET(use,i+vcount-rcount);
  149.         }
  150.         if((p->q2.flags&(VAR|VARADR))==VAR){
  151.             v=p->q2.v;
  152.             i=v->index;
  153.             if(v->nesting==0||(v->flags&USEDASADR)) glflag|=1;
  154.             if(i>=vcount) ierror(0);
  155.             if(!BTST(def,i)) BSET(use,i);
  156.             if((p->q2.flags&DREFOBJ)&&!BTST(def,i+vcount-rcount)) BSET(use,i+vcount-rcount);
  157.         }
  158.     }
  159.     if((p->z.flags&(VAR|DREFOBJ|VARADR))==(VAR|DREFOBJ)){
  160.         v=p->z.v;
  161.         i=v->index;
  162.         if(i>=vcount) ierror(0);
  163.         if(!BTST(def,i)) BSET(use,i);
  164.         if(v->nesting==0||(v->flags&USEDASADR)) glflag|=1;
  165.     }
  166.     /*  Lesen ueber Zeiger alle globalen+address    */
  167.     if((p->q1.flags&DREFOBJ)||(p->q2.flags&DREFOBJ)) glflag|=3;
  168.     /*  Funktionsaufruf braucht alle globalen, statischen und address   */
  169.     if(p->code==CALL) glflag|=7;
  170.     if(glflag){ /*  potentiell aktive Variablen */
  171.         memcpy(tmp,av_drefs,vsize);
  172.         if(glflag&2){   /*  Lesen ueber Zeiger  */
  173.             bvunite(tmp,av_address,vsize);
  174.             bvunite(tmp,av_globals,vsize);
  175.         }
  176.         if(glflag&4) bvunite(tmp,av_statics,vsize);    /*  CALL    */
  177.         bvdiff(tmp,def,vsize);
  178.         bvunite(use,tmp,vsize);
  179.     }
  180.     /*  Ein Wert wird nicht zerstoert, wenn es kein elementare Typ ist und  */
  181.     /*  die Groesse kleiner als die Variable (steht in alle solchen ICs in  */
  182.     /*  q2.reg (hoffe ich).                                                 */
  183.     if((p->z.flags&(VAR|DREFOBJ))==VAR&&((p->z.v->vtyp->flags&15)<=POINTER||p->q2.reg==szof(p->z.v->vtyp))){
  184.         i=p->z.v->index;
  185.         if(i>=vcount) ierror(0);
  186.         if(!BTST(use,i)) BSET(def,i);
  187.         /*  Wenn p geaendert wird, wird auch *p geaendert   */
  188.         if(i<rcount&&!BTST(def,i+vcount-rcount)) BSET(use,i+vcount-rcount);
  189.     }
  190.     if((p->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)){
  191.         i=p->z.v->index+vcount-rcount;
  192.         if(i>=vcount) ierror(0);
  193.         if(!BTST(use,i)) BSET(def,i);
  194.     }
  195. }
  196. void active_vars(struct flowgraph *fg)
  197. /*  analysiert aktive Variablen im Flussgraphen, nomain==0, wenn zu     */
  198. /*  optimierende Funktion main() ist                                    */
  199. {
  200.     struct IC *p;
  201.     int changed,pass;struct flowgraph *g;unsigned int i;
  202.  
  203.     if(DEBUG&1024){printf("analysing active variables\n");/*scanf("%d",&i);*/}
  204.     tmp=mymalloc(vsize);
  205.     /*  av_gen und av_kill fuer jeden Basic Block berechnen */
  206.     if(DEBUG&1024){printf("active_vars(): loop1\n");/*scanf("%d",&i);*/}
  207.     g=fg;
  208.     while(g){
  209.         g->av_gen=mymalloc(vsize);
  210.         memset(g->av_gen,0,vsize);
  211.         g->av_kill=mymalloc(vsize);
  212.         memset(g->av_kill,0,vsize);
  213.         g->av_in=mymalloc(vsize);
  214.         memset(g->av_in,0,vsize);
  215.         g->av_out=mymalloc(vsize);
  216.         memset(g->av_out,0,vsize);
  217.         for(p=g->start;p;p=p->next){
  218.             av_change(p,g->av_gen,g->av_kill);
  219.             if(p==g->end) break;
  220.         }
  221.         g=g->normalout;
  222.     }
  223.  
  224.     /*  av_in und av_out fuer alle Bloecke berechnen    */
  225.     if(DEBUG&1024){printf("active_vars(): loop2\npass: ");/*scanf("%d",&i);*/}
  226.     pass=0;
  227.     do{
  228.         if(DEBUG&1024) {printf(" %d",++pass);fflush(stdout);}
  229.         changed=0;
  230.         g=fg;
  231.         while(g){
  232.             /* out(B)=U in(C) ueber alle Nachfolger C von B */
  233.             memset(g->av_out,0,vsize);  /*  noetig? */
  234.             if(g->branchout) bvunite(g->av_out,g->branchout->av_in,vsize);
  235.             if((!g->end||g->end->code!=BRA)&&g->normalout) bvunite(g->av_out,g->normalout->av_in,vsize);
  236.             /*  Am Ende muessen alle globalen Variablen bekannt sein    */
  237.             if(!g->normalout){
  238.                 bvunite(g->av_out,av_globals,vsize);
  239.                 /*if(!nocall)*/ bvunite(g->av_out,av_statics,vsize);
  240.             }
  241.             /* in(B)=use(B)U(out(B)-def(B)) */
  242.             memcpy(tmp,g->av_out,vsize);
  243.             bvdiff(tmp,g->av_kill,vsize);
  244.             bvunite(tmp,g->av_gen,vsize);
  245.  
  246.             if(!bvcmp(tmp,g->av_in,vsize)){changed=1;memcpy(g->av_in,tmp,vsize);}
  247.             g=g->normalout;
  248.         }
  249.     }while(changed);
  250.     if(DEBUG&1024) printf("\n");
  251.     free(tmp);
  252. }
  253. int dead_assignments(struct flowgraph *fg)
  254. /*  Findet Zuweisungen, die unnoetig sind, da die Variable nie mehr     */
  255. /*  benutzt werden kann.                                                */
  256. {
  257.     int changed=0;struct IC *p;unsigned char *isused;
  258.     unsigned int i,glflag;
  259.     if(DEBUG&1024) printf("searching for dead assignments\n");
  260.     isused=mymalloc(vsize);
  261.     while(fg){
  262.         memcpy(isused,fg->av_out,vsize);
  263.         p=fg->end;
  264.         while(p){
  265.             glflag=0;
  266.             if(p->z.flags&VAR){
  267.                 i=p->z.v->index;
  268.                 if(p->z.flags&DREFOBJ) i+=vcount-rcount;
  269.                 if(!BTST(isused,i)){
  270.                     if(DEBUG&1024){printf("dead assignment deleted:\n");pric2(stdout,p);}
  271.                     if(*p->z.v->identifier&&p->code!=ASSIGN){ error(170,i>=vcount-rcount?"*":"",p->z.v->identifier);}
  272.                     changed=1;
  273.                     if(p==fg->start){remove_IC_fg(fg,p);break;}
  274.                     p=p->prev;remove_IC_fg(fg,p->next);
  275.                     continue;
  276.                 }else{
  277.                     if((p->z.v->vtyp->flags&15)<=POINTER||p->q2.reg==szof(p->z.v->vtyp))
  278.                         BCLR(isused,i);
  279.                     /*  bei Zuweisung an p wird *p aktiv    */
  280.                     if(i<rcount) BSET(isused,i+vcount-rcount);
  281.                 }
  282.             }
  283.             if(p->code!=ADDRESS){
  284.                 if(p->q1.flags&VAR){
  285.                     BSET(isused,p->q1.v->index);
  286.                     if(p->q1.v->nesting==0||(p->q1.v->flags&USEDASADR)) glflag|=1;
  287.                     if(p->q1.flags&DREFOBJ) glflag|=3;
  288.                 }
  289.                 if(p->q2.flags&VAR){
  290.                     BSET(isused,p->q2.v->index);
  291.                     if(p->q2.v->nesting==0||(p->q2.v->flags&USEDASADR)) glflag|=1;
  292.                     if(p->q2.flags&DREFOBJ) glflag|=3;
  293.                 }
  294.             }
  295.             if((p->z.flags&(VAR|DREFOBJ))==(VAR|DREFOBJ)){
  296.                 BSET(isused,p->z.v->index);
  297.                 if(p->z.v->nesting==0||(p->z.v->flags&USEDASADR)) glflag|=1;
  298.             }
  299.             if(p->code==CALL) glflag|=7;
  300.             if(glflag){
  301.                 bvunite(isused,av_drefs,vsize);
  302.                 if(glflag&2){
  303.                     bvunite(isused,av_globals,vsize);
  304.                     bvunite(isused,av_address,vsize);
  305.                 }
  306.                 if(glflag&4) bvunite(isused,av_statics,vsize);
  307.             }
  308.             if(p==fg->start) break;
  309.             p=p->prev;
  310.         }
  311. /*        if(!bvcmp(isused,fg->av_in,vsize)) printf("dead_assignments(): av_in does not match\n");*/
  312.         fg=fg->normalout;
  313.     }
  314.  
  315.     return(changed);
  316. }
  317.  
  318.